Working with spatial data in R I find myself quite often in the need to quickly visually check whether a certain analysis has produced reasonable results. There are two ways I usually do this. Either I:

  1. (sp)plot the data in R and then toggle back and forth between the static plots (I use RStudio) or
  2. save the data to the disk and then open in QGIS or similar to interactively examine the results.

Both these approaches are semi-optimal. Where option 1. is fine for a quick glance at a coarse patterns, it lacks the possibility to have a closer look into the results via zooming and paning. While option 2. provides the interactivity, the detour via the hard disk is annoying (at best), especially when fine-tuning and checking regularly.

I attended this years useR2015! conference in Aalborg (which was marvelous!) and attended the session on interactive graphics in R where Joe Cheng from RStudio presented the leaflet package. Leaflet is great but its rather geared towards manually setting up maps. What a GIS-like functionality would need is some default behaviour for different objects from the spatial universe.

This got me thinking and sparked my enthusiasm to write some wrapper functions for leaflet to provide at least very basic GIS-like interactive graphing capabilities that are directly accessible within RStudio (or the web browser, if you’re not using RStudio). So I sat down and wrote a function called mapView().


mapView() is currently defined for:

mapView() is the main function in the mapview package

By default it provides two base layers between which one can toggle (a standard OpenStreeMap layer and ESRI’s WorldImagery layer). Depending on the object and/or argument settings one or several layers are created (each with it’s own legend). Note that in order to render properly, all layers need to be reprojected to leaflet’s underlying web mercator projection (“+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs”) which in the case of large Raster* objects can be time consuming.


In the following I would like to present a few use case scenarios that highlight the current (admittedly) very limited capabilities of mapView() (largely taken from the help file):

Raster* data objects

RasterLayer

## to install mapview use 
# library(devtools)
# install_github("environmentalinformatics-marburg/mapview")
library(mapview)
library(raster)

data(meuse.grid)
coordinates(meuse.grid) = ~x+y
proj4string(meuse.grid) <- CRS("+init=epsg:28992")
gridded(meuse.grid) = TRUE
meuse_rst <- stack(meuse.grid)

mapView(meuse_rst[[3]])


RasterStack/Brick

If you pass a RasterStack/Brick to mapView() this will create one map layer + legend for each RasterLayer. This is likely to cause problems for larger Stacks as there is currently no way to tell mapView() to only show the legend of the highlighted layer. This means that some of the legends won’t show in the viewer.

mapView(meuse_rst)

There is (to my knowlegde) currently no way to provide this functionality in the leaflet package, though I have seen solutions for this in JavaScript which means that this will likely be available in the future.


Spatial* data objects

SpatialPoints(DataFrame)

data(meuse)
coordinates(meuse) <- ~x+y
proj4string(meuse) <- CRS("+init=epsg:28992")

# only one layer, all info in popups
mapView(meuse, burst = FALSE)

Clicking on any of the points triggers a pop-up window with all the information of this point from the affiliated attribute table (i.e. the @data slot of the SpatialPointsDataFrame) + its location in x/y (lon/lat). If you set burst = TRUE you will get one map layer + legend for each column of your SpatialPointsDataFrame. Again, be cautious here (see RasterStack/Brick above). When passing a SpatialPoints object to mapView() you will get one layer showing only x/y in the pop-ups.


The same functionality is implemeted for

SpatialPolygons(DataFrame)

data("DEU_admin2")
m <- mapView(DEU_admin2, burst = FALSE)
m

and

SpatialLines(DataFrame)

data("atlStorms2005")
mapView(atlStorms2005, burst = FALSE)


Finally, it is possible to overlay/add layers to existing maps. Any combination of objects is possible.

Overlays

## points on polygons ##
centres <- data.frame(coordinates(DEU_admin2))
names(centres) <- c("x", "y")
coordinates(centres) <- ~ x + y
projection(centres) <- projection(DEU_admin2)
mapView(centres, m)

## points on raster ##
m <- mapView(meuse_rst[[3]])
mapView(meuse, m, burst = FALSE)


Thus far, mapView() proves useful for quick glances at (combinations of) spatial data but there are some major issues that I cannot fix at this stage (e.g. the above mentioned legend problem; a query for raster layers would also be desirable). Furthermore, some of the functionality is achieved through dirty hacks, e.g. the pop-up windows for the SpatialPoints* objects are from a layer of additional markers that are drawn invisibly (opacity = 0).

To take this further I would need to fiddle with the JavaScript side of things. This will happen at some stage in the future, but may take some time as I need to acquaint myself with the language (I have no experience with JS). Thus, if a keen person out there is willing and able to help with the JS side of things, don’t hesitate to contact me.

Best,

Tim